package com.rtx.express.service.impl;

import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rtx.api.annotation.RtxExpressApi;
import com.rtx.common.Base64Helper;
import com.rtx.common.HttpUtils;
import com.rtx.edi.model.express.bo.ExpressBO;
import com.rtx.edi.model.express.po.PlExpressApi;
import com.rtx.edi.model.express.po.PlExpressApiConfig;
import com.rtx.edi.model.express.po.PlExpressResult;
import com.rtx.express.service.IExpressService;

@SuppressWarnings("all")
@Service("快递接口ZTO")
public class ZTOExpressAPI  implements IExpressService{
	
	Logger log = LoggerFactory.getLogger(this.getClass());
	
	private static String create_order_url ="http://japi.zto.cn/partnerInsertSubmitagent";
	
	private static String companyid ="e1a6ad381594442e8b19b8480a638588";
	private static String key ="1eea549891b9";
	private static String partner ="ZTO1281682667214386";
	
	/**
	 * 处理中通面请求接口
	 * @return
	 */
	public void callCreaterOrderAPI(ExpressBO bo) {
		PlExpressApi task =  bo.getExpressTask();
		PlExpressApiConfig config = bo.getExpressConfig();
		
		mappingConfigPartner(config);
		try {
			String content_type ="application/x-www-form-urlencoded; charset=utf-8";
			String request = coverToZOPRequest(bo);

			String dataDigestStr ="company_id="+companyid+"&msg_type=submitAgent&data="+request+key;
			String dataDigest =MD5AndBase64(dataDigestStr);//加密方式--先MD5再Base64
			Map headers=new HashMap<>();
			headers.put("x-companyid", companyid);
			headers.put("x-datadigest", dataDigest);
			headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			
			log.info("订单-{}-获取中通快递请求：{}",task.getExternorderkey(),request);
			String param="company_id="+companyid+"&msg_type=submitAgent&data="+URLEncoder.encode(request,"UTF-8");
			String responseStr = HttpUtils.doPost(create_order_url,content_type,headers, param);
			log.info("订单-{}-获取中通快递请求返回：{}",task.getExternorderkey(),responseStr);
			
			JSONObject jsonresult = JSONObject.parseObject(responseStr);
			
			if("true".equals(jsonresult.getString("result"))) {
				bo.setCallCreateOrderAPIData(responseStr);
				bo.setCallCreateOrderAPIResult("ok");
				
				PlExpressResult result = bo.getExpressResultFillSendAndReceiver();
				JSONObject mailNoRes = JSONObject.parseObject(bo.getCallCreateOrderAPIData());
				result.setWaybillNo(mailNoRes.getJSONObject("data").getString("billCode"));
				//{"result":{"bagAddr":"南通转海门","mark":"456- 03-01 6A"},"message":"成功","statusCode":"200","status":true}
				String subAPiResponse = callBagAddrMarkApi(bo,mailNoRes.getJSONObject("data").getString("billCode"));
				
				JSONObject bagMarkRes = JSONObject.parseObject(subAPiResponse).getJSONObject("result");
				result.setZtobagAddr(bagMarkRes.getString("bagAddr"));
				result.setZtomark(bagMarkRes.getString("mark"));
				result.setZtodepotCode("1");
				
				result.setResponseStr(bo.getCallCreateOrderAPIData()+bo.getBagAddrMark());
				result.setExternorderkey(task.getExternorderkey());
				bo.setExpressResult(result);
			}else {
				bo.setCallCreateOrderAPIData(responseStr);
				bo.setMsg(bo.getMsg());
			}

		} catch (Exception e) {
			log.info("订单-{}-获取中通快递单号失败：{}",task.getExternorderkey(),e);
			bo.setMsg("订单-"+task.getExternorderkey()+"-获取中通快递单号失败-"+e.getMessage());
		}
	}
	
	//
	private void mappingConfigPartner(PlExpressApiConfig config) {
		config.setZtoPartner(config.getZtoPartner());
//		if(StringUtils.hasLength(config.getZtoPartner())) {
//		}else {
//			config.setZtoPartner("ZTO1281682667214386");
//		}
	}

	/**
	 * 转化成中通请求
	 * @return
	 */
	public static String coverToZOPRequest(ExpressBO bo) {
		PlExpressApi task =  bo.getExpressTask();
		PlExpressApiConfig config = bo.getExpressConfig();

		//data内容
		Map contentMap=new HashMap<>();
		contentMap.put("partner", config.getZtoPartner());
		if(bo.getZdflag() == true) {
			contentMap.put("id", task.getExternorderkey()+System.currentTimeMillis());
		}else {
			contentMap.put("id", task.getExternorderkey());
		}
		contentMap.put("typeId", "1");

		//带*必填动态数据
		//发货地址
		Map senderMap =new HashMap<>();
		senderMap.put("address", task.getSendAddress());
		senderMap.put("city", task.getSendProvince()+task.getSendCity()+task.getSendCounty());
		senderMap.put("company",task.getSendCompanyName());
		senderMap.put("phone", task.getSendPhone());
		senderMap.put("mobile", task.getSendMobile());
		senderMap.put("name",task.getSendName());

		contentMap.put("sender", senderMap);

		//收货地址
		Map receiveMap=new HashMap<>();
		receiveMap.put("address", task.getReceiverAddress());
		receiveMap.put("city",task.getReceiverProvince()+task.getReceiverCity()+task.getReceiverCounty());
		receiveMap.put("mobile", task.getReceiverMobile());
		receiveMap.put("name", task.getReceiverName());
		receiveMap.put("phone", task.getReceiverPhone());

		contentMap.put("receiver", receiveMap);
		contentMap.put("remark", "备注选填");

		return JSON.toJSONString(contentMap);
	}
	

	//中通签名方式
	public static String MD5AndBase64(String param) throws NoSuchAlgorithmException{
		MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(param.getBytes(Charset.forName("UTF-8")));
        byte b[] = md.digest();
	
		String dataDigest =Base64Helper.encode(b);
		return dataDigest;
	}
	
	private String callBagAddrMarkApi(ExpressBO bo,String billCode) throws Exception {
		PlExpressApi task =  bo.getExpressTask();
		PlExpressApiConfig config = bo.getExpressConfig();
		String content_type ="application/x-www-form-urlencoded; charset=utf-8";
		String url ="http://japi.zto.cn/bagAddrMarkGetmark";
		//获取运单号后，还需要获取三段码
		  
		JSONObject reqmap=new JSONObject();
		reqmap.put("unionCode", billCode);
		reqmap.put("send_province", task.getSendProvince());
		reqmap.put("send_city", task.getSendCity());
		reqmap.put("send_district", task.getSendCounty());
		reqmap.put("receive_province", task.getReceiverProvince());
		reqmap.put("receive_city", task.getReceiverCity());
		reqmap.put("receive_district", task.getReceiverCounty());
		reqmap.put("receive_address", task.getReceiverAddress());
		
		String requestStr = reqmap.toJSONString();
		
		String reqparam="company_id="+companyid+"&msg_type=GETMARK&data="+requestStr+key;
		
		String datadigest =MD5AndBase64(reqparam);
		Map header=new HashMap<>();
		header.put("x-companyid", companyid);
		header.put("x-datadigest", datadigest);
		
		String params="company_id="+companyid+"&msg_type=GETMARK&data="+URLEncoder.encode(requestStr,"UTF-8");
		log.info("订单-{}-获取中通快递请求获取大头笔：{}",task.getExternorderkey(),requestStr);
		String responseStr = HttpUtils.doPost(url,content_type,header, params);
		log.info("订单-{}-获取中通快递请求获取大头笔响应：{}",task.getExternorderkey(),responseStr);
		return responseStr;
	}

	@Override
	public void handleCreaterOrderAPIResponse(ExpressBO bo) {
//		PlExpressApi task =  bo.getExpressTask();
//		try {
//			if("ok".equals(bo.getCallCreateOrderAPIResult())) {
//				PlExpressResult result = new PlExpressResult();
//				JSONObject mailNoRes = JSONObject.parseObject(bo.getCallCreateOrderAPIData());
//				result.setMailNo(mailNoRes.getJSONObject("data").getString("billCode"));
//				JSONObject bagMarkRes = JSONObject.parseObject(bo.getBagAddrMark()).getJSONObject("result");
//				result.setBagAddr(bagMarkRes.getString("bagAddr"));
//				result.setMark(bagMarkRes.getString("mark"));
//				result.setDepotCode("1");
//				result.setResponseStr(bo.getCallCreateOrderAPIData()+bo.getBagAddrMark());
//				result.setExternorderkey(task.getExternorderkey());
//				bo.setExpressResult(result);
//			}
//		} catch (Exception e) {
//			log.info("订单-{}-获取中通快递单 解析响应结果-{}-异常-{}",task.getExternorderkey(),bo.getCallCreateOrderAPIData(),e);
//			bo.setMsg(bo.getMsg());
//		}
		
	}  
}
